const { ethers } = require('ethers');

(async () => {
  const privateKey = "fec4de8b60d3f9ef0003fc4143d2675eb6c3dbced35633e8aa7854abbe8e0459";
  const prefix = "\x19Ethereum Signed Message:\n32";
  const address = '0x21e35e6e68E465C96e0186a8FeEE356aD9A79Ee3';
  const dataString = '这是一个中文字符串';
  const num = ethers.BigNumber.from(123);
  let list = [
    ethers.BigNumber.from(36),
    ethers.BigNumber.from(69),
    ethers.BigNumber.from(555)
  ];

  // Convert list to a byte array
  let byteList = [];
  for (let i = 0; i < list.length; i++) {
    const paddedBytes = ethers.utils.arrayify(list[i]);
    byteList = byteList.concat(Array.from(paddedBytes));
  }
  const encodedList = new Uint8Array(byteList);
  const hexString = ethers.utils.hexlify(encodedList);
  const encodedListBytes = ethers.utils.formatBytes32String(hexString);
  const dataBytes = ethers.utils.formatBytes32String(dataString);

  let messageHash = ethers.utils.solidityKeccak256(
    ["uint32", "bytes32", "string", "address"],
    [num, encodedListBytes, dataBytes, address]
  );
  console.log("输出hash", messageHash);

  let msg = ethers.utils.keccak256(
    ethers.utils.solidityPack(
      ["string", "bytes32"],
      [prefix, messageHash]
    )
  );

  function signatureToHex(signature) {
    return '0x' + signature.slice(2);
  }

  // 使用私钥签名消息
  const wallet = new ethers.Wallet(privateKey);
  const signature = await wallet.signMessage(ethers.utils.arrayify(msg));
  console.log('signature', signature);
  const signResult = signatureToHex(signature);
  console.log('signResult', signResult);
  
  // 验证签名
  const isValidSignature = ethers.utils.verifyMessage(msg, signature);
  console.log('Is Valid Signature:', isValidSignature);
})();